package com.yupi.springbootinit.service.workflow;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yupi.springbootinit.mapper.WorkflowTaskMapper;
import com.yupi.springbootinit.model.entity.WorkflowTask;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.yupi.springbootinit.service.SalesOrderService;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.yupi.springbootinit.service.workflow.WorkflowTaskConstants.*;

/**
 * 工作流任务操作服务
 */
@Slf4j
@Service
public class WorkflowTaskOperationService {

    @Resource
    private WorkflowTaskMapper workflowTaskMapper;

    @Resource
    private SalesOrderService salesOrderService;

    /**
     * ✅ 完成发布批次任务（修复：添加父任务检查）
     */
    public boolean completePublishBatchTaskForBatch(Long batchId, Long completedBy, String completedByName, String remark) {
        if (batchId == null) return false;

        log.info("========== 开始完成批次发布任务 ==========");
        log.info("batchId={}, completedBy={}, completedByName={}", batchId, completedBy, completedByName);

        // 1. 查询任务信息（需要获取 parentTaskId）
        QueryWrapper<WorkflowTask> queryQw = new QueryWrapper<>();
        queryQw.eq("bizType", BIZ_TYPE_PROCESS_BATCH)
                .eq("bizId", batchId)
                .eq("taskType", TASK_TYPE_PUBLISH_BATCH)
                .eq("isDelete", 0)
                .last("LIMIT 1");
        WorkflowTask task = workflowTaskMapper.selectOne(queryQw);

        if (task == null) {
            log.warn("❌ 未找到对应的发布批次待办: batchId={}", batchId);
            return false;
        }

        log.info("查询到任务: taskId={}, parentTaskId={}, taskStatus={}",
                task.getId(), task.getParentTaskId(), task.getTaskStatus());

        // 2. 更新任务状态
        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("id", task.getId())
                .in("taskStatus", STATUS_PENDING, STATUS_IN_PROGRESS)
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setTaskStatus(STATUS_DONE);
        update.setCompletedTime(LocalDateTime.now());
        update.setCompletionRemark(Objects.toString(remark, "批次发布完成"));
        update.setClaimedBy(completedBy);
        update.setClaimedByName(completedByName);
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;

        if (success) {
            log.info("✅ 批次发布任务完成成功: taskId={}, batchId={}, completedBy={}, completedByName={}",
                    task.getId(), batchId, completedBy, completedByName);

            // ✅ 3. 检查并完成父任务
            if (task.getParentTaskId() != null) {
                checkAndCompleteParentTask(task.getParentTaskId(), completedBy, completedByName);
            } else {
                log.info("⚠️ 该任务无父任务，跳过父任务检查: taskId={}", task.getId());
            }
        } else {
            log.warn("❌ 批次发布任务完成失败: taskId={}, batchId={}, rows={}",
                    task.getId(), batchId, rows);
        }

        log.info("========== 批次发布任务完成流程结束 ==========");
        return success;
    }

    /**
     * 🔧 优化：检查并完成父任务
     *
     * 触发时机：子任务完成后调用
     * 逻辑：
     *   1. 查询父任务的所有子任务
     *   2. 检查是否所有子任务都已完成
     *   3. 如果是，则自动完成父任务
     *   4. 如果父任务是销售订单的排期任务，更新订单状态
     *
     * @param parentTaskId 父任务ID
     * @param completedBy 完成人ID（用于日志）
     * @param completedByName 完成人姓名（用于日志）
     */
    private void checkAndCompleteParentTask(Long parentTaskId, Long completedBy, String completedByName) {
        if (parentTaskId == null) {
            return;
        }

        log.info("========== 开始检查父任务完成条件 ==========");
        log.info("parentTaskId={}, completedBy={}, completedByName={}", parentTaskId, completedBy, completedByName);

        // 1. 查询父任务信息
        WorkflowTask parentTask = workflowTaskMapper.selectById(parentTaskId);
        if (parentTask == null || (parentTask.getIsDelete() != null && parentTask.getIsDelete() == 1)) {
            log.warn("⚠️ 父任务不存在或已删除: parentTaskId={}", parentTaskId);
            return;
        }

        // 如果父任务已完成，跳过
        if (STATUS_DONE.equals(parentTask.getTaskStatus()) || STATUS_COMPLETED.equals(parentTask.getTaskStatus())) {
            log.info("✅ 父任务已完成，跳过检查: parentTaskId={}, status={}", parentTaskId, parentTask.getTaskStatus());
            return;
        }

        log.info("父任务信息: taskType={}, bizType={}, bizId={}, status={}",
                parentTask.getTaskType(), parentTask.getBizType(), parentTask.getBizId(), parentTask.getTaskStatus());

        // 2. 查询所有子任务
        QueryWrapper<WorkflowTask> subQw = new QueryWrapper<>();
        subQw.eq("parentTaskId", parentTaskId)
                .eq("isDelete", 0);
        List<WorkflowTask> subTasks = workflowTaskMapper.selectList(subQw);

        if (subTasks == null || subTasks.isEmpty()) {
            log.warn("⚠️ 父任务无子任务: parentTaskId={}", parentTaskId);
            return;
        }

        log.info("父任务的子任务数量: parentTaskId={}, 子任务总数={}", parentTaskId, subTasks.size());

        // 3. 检查是否所有子任务都已完成
        long completedCount = subTasks.stream()
                .filter(t -> STATUS_DONE.equals(t.getTaskStatus()) || STATUS_COMPLETED.equals(t.getTaskStatus()))
                .count();

        long totalCount = subTasks.size();

        log.info("子任务完成情况: parentTaskId={}, 已完成={}, 总数={}",
                parentTaskId, completedCount, totalCount);

        if (completedCount < totalCount) {
            log.info("⚠️ 仍有未完成的子任务，暂不完成父任务: parentTaskId={}, 完成={}/{}",
                    parentTaskId, completedCount, totalCount);
            return;
        }

        // 4. 所有子任务都已完成，自动完成父任务
        log.info("✅ 所有子任务都已完成，开始自动完成父任务: parentTaskId={}", parentTaskId);

        try {
            LocalDateTime now = LocalDateTime.now();

            // 🔧 使用 UpdateWrapper 确保并发安全
            UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
            uw.eq("id", parentTaskId)
                    .eq("isDelete", 0)
                    .notIn("taskStatus", Arrays.asList(STATUS_DONE, STATUS_COMPLETED));  // 🔧 防止重复完成

            WorkflowTask update = new WorkflowTask();
            update.setTaskStatus(STATUS_DONE);
            update.setCompletedTime(now);
            update.setCompletionRemark(String.format("所有%d个批次发布任务已完成，系统自动完成", totalCount));
            update.setUpdateTime(now);

            int rows = workflowTaskMapper.update(update, uw);

            if (rows > 0) {
                log.info("✅ 父任务自动完成成功: parentTaskId={}, 子任务数={}, completedBy={}, completedByName={}",
                        parentTaskId, totalCount, completedBy, completedByName);

                // 5. 如果父任务是销售订单的排期任务，更新订单状态
                if (TASK_TYPE_CREATE_SCHEDULE.equals(parentTask.getTaskType()) &&
                        BIZ_TYPE_SALES_ORDER.equals(parentTask.getBizType())) {
                    try {
                        salesOrderService.updateOrderStatus(
                                parentTask.getBizId(),
                                "PLAN_ISSUED",
                                "生产计划已下发",
                                null
                        );
                        log.info("✅ 更新订单状态成功: orderId={}, status=PLAN_ISSUED", parentTask.getBizId());
                    } catch (Exception e) {
                        log.warn("⚠️ 更新订单状态失败（不影响任务完结）：orderId={}, targetStatus={}",
                                parentTask.getBizId(), "PLAN_ISSUED", e);
                    }
                }
            } else {
                log.warn("⚠️ 父任务自动完成失败（可能已被其他线程完成）: parentTaskId={}, rows={}",
                        parentTaskId, rows);
            }

        } catch (Exception e) {
            log.error("❌ 自动完成父任务失败: parentTaskId={}", parentTaskId, e);
            // 不抛异常，避免影响子任务的完成
        }

        log.info("========== 父任务检查流程结束 ==========");
    }

    /**
     * 完成生产排期任务
     */
    public boolean completeScheduleTaskForSalesOrder(Long salesOrderId, Long completedBy, String completedByName, String remark) {
        if (salesOrderId == null) return false;

        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("bizType", BIZ_TYPE_SALES_ORDER)
                .eq("bizId", salesOrderId)
                .eq("taskType", TASK_TYPE_CREATE_SCHEDULE)
                .in("taskStatus", STATUS_PENDING, STATUS_IN_PROGRESS)
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setTaskStatus(STATUS_DONE);
        update.setCompletedTime(LocalDateTime.now());
        update.setCompletionRemark(Objects.toString(remark, "全部批次发布完成"));
        update.setClaimedBy(completedBy);
        update.setClaimedByName(completedByName);
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;
        if (success) {
            try {
                // 全部批次发布完成 -> 父排期待办完成 -> 推进订单状态到 PLAN_ISSUED（计划已下发）
                salesOrderService.updateOrderStatus(salesOrderId, "PLAN_ISSUED", "生产计划已下发", null);
            } catch (Exception e) {
                log.warn("更新订单状态失败（不影响任务完结）：orderId={}, targetStatus={}", salesOrderId, "PLAN_ISSUED", e);
            }
        }
        log.info("完结PMC父待办(CREATE_SCHEDULE): salesOrderId={}, success={}, affectedRows={}", salesOrderId, success, rows);
        return success;
    }

    /**
     * 完成工程部待办：创建工艺单完成（幂等，含并发条件）
     */
    public boolean completeProcessSheetTaskForSalesOrder(Long salesOrderId, Long completedBy, String completedByName) {
        if (salesOrderId == null) {
            return false;
        }

        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("bizType", BIZ_TYPE_SALES_ORDER)
                .eq("bizId", salesOrderId)
                .eq("taskType", TASK_TYPE_CREATE_PROCESS_SHEET)
                .in("taskStatus", STATUS_PENDING, STATUS_IN_PROGRESS)
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setTaskStatus(STATUS_DONE);
        update.setCompletedTime(LocalDateTime.now());
        update.setCompletionRemark("工艺单创建完成，自动完结");
        update.setClaimedBy(completedBy);
        update.setClaimedByName(completedByName);
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;
        log.info("完结工程部待办: bizId={}, success={}, affectedRows={}", salesOrderId, success, rows);
        return success;
    }

    /**
     * 认领任务
     *
     * 注意：PUBLISH_BATCH（批次发布）类型任务不允许认领，由系统自动完成
     *
     * 🔧 新增：认领父任务时，自动认领其所有子任务
     */
    public boolean claimTask(Long taskId, Long userId, String userName, Long departmentId) {
        if (taskId == null || userId == null || departmentId == null) {
            return false;
        }

        log.info("========== 开始认领任务 ==========");
        log.info("taskId={}, userId={}, userName={}, departmentId={}", taskId, userId, userName, departmentId);

        // ✅ 新增：校验任务是否允许认领
        WorkflowTask task = workflowTaskMapper.selectById(taskId);
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            log.warn("❌ 认领失败：任务不存在或已删除, taskId={}", taskId);
            return false;
        }

        log.info("查询到任务: taskType={}, bizType={}, bizId={}, taskStatus={}",
                task.getTaskType(), task.getBizType(), task.getBizId(), task.getTaskStatus());

        // ✅ 关键修复：PUBLISH_BATCH类型任务不允许认领
        if (TASK_TYPE_PUBLISH_BATCH.equals(task.getTaskType())) {
            log.warn("❌ 认领失败：PUBLISH_BATCH类型任务不允许认领, taskId={}, taskType={}", taskId, task.getTaskType());
            return false;
        }

        // 认领父任务
        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("id", taskId)
                .eq("departmentId", departmentId)
                .eq("taskStatus", STATUS_PENDING)
                .isNull("claimedBy")
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setClaimedBy(userId);
        update.setClaimedByName(userName);
        update.setClaimedTime(LocalDateTime.now());
        update.setTaskStatus(STATUS_IN_PROGRESS);
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;

        if (success) {
            log.info("✅ 任务认领成功: taskId={}, userId={}, userName={}, taskType={}",
                    taskId, userId, userName, task.getTaskType());

            // 🔧 新增：自动认领子任务
            claimSubTasks(taskId, userId, userName);
        } else {
            log.warn("❌ 任务认领失败: taskId={}, userId={}, rows={}", taskId, userId, rows);
        }

        log.info("========== 任务认领流程结束 ==========");
        return success;
    }

    /**
     * 🔧 新增：自动认领子任务
     *
     * 触发时机：父任务被认领后调用
     * 逻辑：
     *   1. 查询父任务的所有未认领子任务
     *   2. 批量更新子任务的认领信息
     *   3. 将子任务状态设置为 IN_PROGRESS
     *
     * 🔒 安全性：
     *   - 只认领 PENDING 状态且未被认领的子任务
     *   - 使用批量更新，性能更好
     *   - 失败不影响父任务认领（仅记录日志）
     *
     * @param parentTaskId 父任务ID
     * @param userId 认领人ID
     * @param userName 认领人姓名
     */
    private void claimSubTasks(Long parentTaskId, Long userId, String userName) {
        if (parentTaskId == null) {
            return;
        }

        log.info("========== 开始自动认领子任务 ==========");
        log.info("parentTaskId={}, userId={}, userName={}", parentTaskId, userId, userName);

        try {
            // 1. 查询所有未认领的子任务
            QueryWrapper<WorkflowTask> queryQw = new QueryWrapper<>();
            queryQw.eq("parentTaskId", parentTaskId)
                    .eq("taskStatus", STATUS_PENDING)
                    .isNull("claimedBy")
                    .eq("isDelete", 0);

            List<WorkflowTask> subTasks = workflowTaskMapper.selectList(queryQw);

            if (subTasks == null || subTasks.isEmpty()) {
                log.info("⚠️ 该任务无未认领的子任务: parentTaskId={}", parentTaskId);
                return;
            }

            log.info("查询到未认领的子任务: parentTaskId={}, 子任务数={}", parentTaskId, subTasks.size());

            // 2. 批量更新子任务
            LocalDateTime now = LocalDateTime.now();

            UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
            uw.eq("parentTaskId", parentTaskId)
                    .eq("taskStatus", STATUS_PENDING)
                    .isNull("claimedBy")
                    .eq("isDelete", 0);

            WorkflowTask update = new WorkflowTask();
            update.setClaimedBy(userId);
            update.setClaimedByName(userName);
            update.setClaimedTime(now);
            update.setTaskStatus(STATUS_IN_PROGRESS);
            update.setUpdateTime(now);

            int count = workflowTaskMapper.update(update, uw);

            if (count > 0) {
                log.info("✅ 批量认领子任务成功: parentTaskId={}, 成功认领{}个子任务, userId={}, userName={}",
                        parentTaskId, count, userId, userName);

                // 🔧 可选：记录每个子任务的详细信息（用于审计）
                subTasks.forEach(subTask -> {
                    log.info("  - 子任务已认领: taskId={}, taskType={}, bizId={}, bizNumber={}",
                            subTask.getId(), subTask.getTaskType(), subTask.getBizId(), subTask.getBizNumber());
                });
            } else {
                log.warn("⚠️ 批量认领子任务失败（可能已被其他线程认领）: parentTaskId={}, rows={}",
                        parentTaskId, count);
            }

        } catch (Exception e) {
            log.error("❌ 自动认领子任务失败: parentTaskId={}", parentTaskId, e);
            // 🔒 不抛异常，避免影响父任务的认领
        }

        log.info("========== 子任务认领流程结束 ==========");
    }

    /**
     * 🔧 修复：完成任务（通用方法，增加父任务检查）
     */
    public boolean completeTask(Long taskId, Long userId, String userName, String remark) {
        if (taskId == null || userId == null) {
            return false;
        }

        log.info("========== 开始完成任务 ==========");
        log.info("taskId={}, userId={}, userName={}", taskId, userId, userName);

        // 🔧 1. 查询任务信息（需要获取 parentTaskId）
        WorkflowTask task = workflowTaskMapper.selectById(taskId);
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            log.warn("❌ 完成任务失败：任务不存在或已删除, taskId={}", taskId);
            return false;
        }

        log.info("查询到任务: taskType={}, bizType={}, bizId={}, parentTaskId={}, taskStatus={}",
                task.getTaskType(), task.getBizType(), task.getBizId(), task.getParentTaskId(), task.getTaskStatus());

        // 2. 更新任务状态
        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("id", taskId)
                .eq("claimedBy", userId)
                .eq("taskStatus", STATUS_IN_PROGRESS)
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setTaskStatus(STATUS_DONE);
        update.setCompletedTime(LocalDateTime.now());
        update.setCompletionRemark(Objects.toString(remark, "任务完成"));
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;

        if (success) {
            log.info("✅ 任务完成成功: taskId={}, userId={}, userName={}", taskId, userId, userName);

            // 🔧 新增：检查并完成父任务
            if (task.getParentTaskId() != null) {
                log.info("检测到父任务，开始检查是否需要自动完成父任务: parentTaskId={}", task.getParentTaskId());
                checkAndCompleteParentTask(task.getParentTaskId(), userId, userName);
            } else {
                log.info("⚠️ 该任务无父任务，跳过父任务检查: taskId={}", taskId);
            }
        } else {
            log.warn("❌ 任务完成失败: taskId={}, userId={}, rows={}", taskId, userId, rows);
        }

        log.info("========== 任务完成流程结束 ==========");
        return success;
    }

    /**
     * 完成RDO订单的生产排期任务
     */
    public boolean completeScheduleTaskForRdoOrder(Long rdoOrderId, Long completedBy, String completedByName, String remark) {
        if (rdoOrderId == null || completedBy == null) {
            return false;
        }

        UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
        uw.eq("bizType", BIZ_TYPE_SALES_ORDER) // 注意：RDO订单也使用SALES_ORDER作为bizType
                .eq("bizId", rdoOrderId)
                .eq("taskType", TASK_TYPE_CREATE_SCHEDULE)
                .in("taskStatus", STATUS_PENDING, STATUS_IN_PROGRESS)
                .eq("isDelete", 0);

        WorkflowTask update = new WorkflowTask();
        update.setTaskStatus(STATUS_DONE);
        update.setCompletedTime(LocalDateTime.now());
        update.setCompletionRemark(Objects.toString(remark, "全部批次发布/或删除完成"));
        update.setClaimedBy(completedBy);
        update.setClaimedByName(completedByName);
        update.setUpdateTime(LocalDateTime.now());

        int rows = workflowTaskMapper.update(update, uw);
        boolean success = rows > 0;
        if (success) {
            try {
                // RDO 订单同样推进到 PLAN_ISSUED
                salesOrderService.updateOrderStatus(rdoOrderId, "PLAN_ISSUED", "生产计划已下发", null);
            } catch (Exception e) {
                log.warn("更新RDO订单状态失败（不影响任务完结）：orderId={}, targetStatus={}", rdoOrderId, "PLAN_ISSUED", e);
            }
        }
        log.info("完成RDO排期待办: rdoOrderId={}, completedBy={}, success={}, affectedRows={}", rdoOrderId, completedBy, success, rows);
        return success;
    }
    /**
     * 完成生产工单任务（如果所有工序都已完成）
     *
     * @param batchId 批次ID
     * @param remark 完成备注
     * @return true-任务完成成功, false-任务未完成（不是最后一道工序或任务不存在）
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean completeProductionWorkorderTaskIfAllStepsFinished(Long batchId, String remark) {
        if (batchId == null) {
            log.warn("完成生产工单任务失败: batchId为空");
            return false;
        }

        log.info("检查生产工单任务是否需要完成: batchId={}", batchId);

        // 1. 查询生产工单任务
        LambdaQueryWrapper<WorkflowTask> taskQw = new LambdaQueryWrapper<>();
        taskQw.eq(WorkflowTask::getBizType, "PROCESS_BATCH")
                .eq(WorkflowTask::getBizId, batchId)
                .eq(WorkflowTask::getTaskType, "PRODUCTION_WORKORDER")
                .eq(WorkflowTask::getIsDelete, 0)
                .last("LIMIT 1");
        WorkflowTask productionTask = workflowTaskMapper.selectOne(taskQw);

        if (productionTask == null) {
            log.warn("⚠️ 未找到对应的生产工单任务: batchId={}", batchId);
            return false;
        }

        // 2. 幂等性检查：任务已完成则直接返回
        if ("DONE".equals(productionTask.getTaskStatus())) {
            log.info("ℹ️ 生产任务已是完成状态，跳过更新: taskId={}, batchId={}",
                    productionTask.getId(), batchId);
            return true;
        }

        // 3. 完成生产任务
        LocalDateTime now = LocalDateTime.now();
        UpdateWrapper<WorkflowTask> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", productionTask.getId())
                .eq("is_delete", 0)
                .ne("task_status", "DONE")
                .set("task_status", "DONE")
                .set("completed_time", now)
                .set("completion_remark", StringUtils.defaultString(remark, "所有工序已完成（含质检）"))
                .set("update_time", now)
                .setSql("version = version + 1");

        int rows = workflowTaskMapper.update(null, updateWrapper);
        if (rows > 0) {
            log.info("✅ 生产任务已自动完成: taskId={}, batchId={}, remark={}",
                    productionTask.getId(), batchId, remark);
            return true;
        } else {
            log.warn("⚠️ 生产任务完成失败（可能被并发修改或已完成）: taskId={}, batchId={}",
                    productionTask.getId(), batchId);

            // 重新查询确认状态
            WorkflowTask recheck = workflowTaskMapper.selectById(productionTask.getId());
            if (recheck != null && "DONE".equals(recheck.getTaskStatus())) {
                log.info("ℹ️ 重新查询确认任务已完成: taskId={}", productionTask.getId());
                return true;
            }

            return false;
        }
    }

}